﻿using System;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Controls;

using GroupChallenge.Web;
using GroupChallenge.Web.Services;

namespace GroupChallenge
{
    public partial class PlayersView : Page
    {
        #region Initialization

        private readonly GroupChallengeDomainContext _GroupChallengeDomainContext = new GroupChallengeDomainContext();

        public PlayersView()
        {
            InitializeComponent();

            this.Title = ApplicationStrings.PlayersViewTitle;

            Loaded += new RoutedEventHandler(PlayersView_Loaded);
        }

        #endregion                              // Initialization

        #region UI Events

        private void PlayersView_Loaded(object sender, RoutedEventArgs e)
        {
            RefreshPlayerList();
        }

        // NOTE:  This RIA Service call is the way we get complex objects returned without the depricated Invoke/ServiceOperation methods.  
        //        We only get simple return types otherwise.  We want a string so we return a result id and friendly string object in a collection.
        private void JoinButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            JoinPlayer();
        }

        private void LeaveButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            if (MessageBoxResult.OK == MessageBox.Show("Leave the game?", "Confirm Leave", MessageBoxButton.OKCancel))
            {
                _GroupChallengeDomainContext.LeaveGame(NickNameTextBox.Text, CompletedLeaveGame, null);
            }
        }

        private void RefreshListButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            RefreshPlayerList();
        }

        #endregion                              // UI Events

        #region Private Methods

        private void JoinPlayer()
        {
            try
            {
                int playerId = 0;
                Int32.TryParse(PlayerIdTextBox.Text, out playerId);
                string newNickName = NickNameTextBox.Text;

                var query = _GroupChallengeDomainContext.JoinGameQuery(newNickName, FullNameTextBox.Text, playerId);
                _GroupChallengeDomainContext.Load(query, CompletedJoinLoad, true);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Unable to join the game.  Reason: " + ex.Message, "Join Game Error", MessageBoxButton.OK);
            }
        }

        private void CompletedJoinLoad(LoadOperation loadOperation)
        {
            if (loadOperation.HasError)
            {
                loadOperation.MarkErrorAsHandled();

                MessageBox.Show("Unable to join the game.\r\n\r\nReason: " + loadOperation.Error.Message, "Join Game Error", MessageBoxButton.OK);
            }
            else
            {
                if (null != loadOperation.Entities)
                {
                    FriendlyResult friendlyResult = loadOperation.Entities.FirstOrDefault() as FriendlyResult;
                    if (null != friendlyResult)
                    {
                        RefreshPlayerList();

                        if (friendlyResult.ResultId == 1)         // Success
                            MessageBox.Show(friendlyResult.FriendlyText, "Success", MessageBoxButton.OK);
                        else
                            MessageBox.Show(friendlyResult.FriendlyText, "Failure", MessageBoxButton.OK);
                    }
                }
            }
        }

        private void CompletedLeaveGame(InvokeOperation invokeOperation)
        {
            if (invokeOperation.HasError)
            {
                invokeOperation.MarkErrorAsHandled();

                MessageBox.Show("Unable to propertly leave the game.\r\n\r\nReason: " + invokeOperation.Error.Message, "Leave Game Error", MessageBoxButton.OK);
            }
            else
            {
                RefreshPlayerList();
            }
        }

        private void RefreshPlayerList()
        {
            _GroupChallengeDomainContext.Players.Clear();

            EntityQuery<Player> playerQuery = _GroupChallengeDomainContext.GetPlayersQuery();

            _GroupChallengeDomainContext.Load(playerQuery, CompletedRefreshPlayerList, true);

            PlayersDataGrid.ItemsSource = _GroupChallengeDomainContext.Players;
        }

        private void CompletedRefreshPlayerList(LoadOperation loadOperation)
        {
            if (loadOperation.HasError)
            {
                loadOperation.MarkErrorAsHandled();

                MessageBox.Show("Unable to properly refresh the game player list.\r\n\r\nReason: " + loadOperation.Error.Message, "Refresh List Error", MessageBoxButton.OK);
            }
        }

        #endregion                              // Private Methods
    }
}